package com.huilian.iotbox.admin.wap.service.impl;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huilian.iotbox.admin.wap.dao.*;
import com.huilian.iotbox.admin.wap.service.*;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.dto.*;
import com.huilian.iotbox.data.enums.*;
import com.huilian.iotbox.data.utils.DateTimeUtils;
import com.huilian.iotbox.data.vo.*;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author 谢洛涛
 * @date 2021/5/8 10:05
 */
@Service
@Slf4j
public class StatsUserServiceImpl implements StatsUserService {

    @Resource
    private StatsUserDao statsUserDao;
    @Autowired
    private OrderService orderService;
    @Autowired
    private ThreadPoolExecutor executor;
    @Autowired
    private StatsStoreDao statsStoreDao;
    @Autowired
    MerchantStoreService merchantStoreService;
    @Autowired
    private StatsStoreService statsStoreService;
    @Resource
    private DeviceService deviceService;

    @Resource
    private StatsPackageUserDao statsPackageUserDao;

    @Resource
    private MemberDao memberDao;

    @Autowired
    private MemberStoreBalanceService memberStoreBalanceService;

    @Resource
    private StatsAppDeviceService statsAppDeviceService;

    @Resource
    private StatsDeviceService statsDeviceService;

    @Getter
    public enum BranchIdEnum {
        CASH_INCOME(1, "现金收入"),
        ONLINE_REVENUE(2, "在线支付"),
        ACTIVITY_REVENUE(3, "活动收入"),
        OUT_COIN_TOTAL(4, "出币合计"),
        ONLINE_OUT_COIN(5, "线上出币"),
        CASH_OUT_COIN(6, "现金出币"),
        INSERT_COIN_TOTAL(7, "投币合计"),
        ONLINE_INSERT_COIN(8, "线上投币"),
        OFFLINE_INSERT_COIN(9, "线下投币"),
        GIFT_CONSUME(10, "礼品消耗"),
//        GIFT_COST(10, "礼品成本"),
//        YIELD(10, "出品率"),
        TURNOVER(13, "营业额"),
        MEITUAN(14,"美团核销收入"),
        DOUYIN(15,"抖音核销收入"),
        MEMBER_COINS(18,"会员取币"),
        DOUYIN_COINS(19,"抖音核销出币"),
        MEITUAN_COINS(20,"美团核销出币"),
        ARTIFICIAL_COINS(21,"人工出币"),
        WEIXIN_SECKILL_VERIFY(22,"微信秒杀核销"),
        WEIXIN_GROUP_BUYING_VERIFY(23,"微信拼团核销"),
        WEIXIN_VOUCHER_VERIFY(24,"微信凭证核销"),
        WEIXIN_VERIFY(25,"微信核销"),
        GAME_COIN_RED_PACKET(26,"游戏币红包"),
        DISTRIBUTE_BENEFIT(27,"派发福利"),
        GROUP_BENEFIT(28,"加群福利"),
        ;

        //枚举值所包含的属性
        private Integer id;
        private String desc;

        //构造方法
        BranchIdEnum(Integer id, String desc) {
            this.id = id;
            this.desc = desc;
        }
    }

    @Override
    public StatsUserVo findStatsUser(StatsUserDto statsUserDto) {
        statsUserDto.setStatsType(StatsTypeEnum.statsUser.getCode());

        StatsUserVo todayStatsUserVo;
        StatsUserVo thisMonthStatsUserVo;
        StatsUserVo statsUserVo = null;
        //当天
        if (statsUserDto.getDayType() == 0) {
            statsUserVo = this.findTodayStatsUserFromOrder(statsUserDto);
        } else if (statsUserDto.getDayType() == -1) {
            //根据日期范围查询
            statsUserDto.setType(1);
            statsUserVo = this.findFromStatsUser(statsUserDto);

            if (statsUserDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                todayStatsUserVo = this.findTodayStatsUserFromOrder(statsUserDto);
                this.twoStatsUserVoAdd(statsUserVo, todayStatsUserVo);
            }
        } else {
            switch (statsUserDto.getDayType()) {
                case 1:
                    //昨天
                    statsUserDto.setStartDateStr(DateTimeUtils.getYesterday());
                    statsUserDto.setEndDateStr(DateTimeUtils.getYesterday());
                    statsUserDto.setType(1);
                    statsUserVo = this.findFromStatsUser(statsUserDto);
                    break;
                case 2:
                    //本周
                    statsUserDto.setStartDateStr(DateTimeUtils.getWeekFirstDay());
                    statsUserDto.setEndDateStr(DateTimeUtils.getWeekLastDay());
                    statsUserDto.setType(1);
                    statsUserVo = this.findFromStatsUser(statsUserDto);
                    //当天
                    todayStatsUserVo = this.findTodayStatsUserFromOrder(statsUserDto);
                    this.twoStatsUserVoAdd(statsUserVo, todayStatsUserVo);

                    break;
                case 3:
                    //本月
                    statsUserVo = this.getThisMonth(statsUserDto);
                    break;
                case 4:
                    //上月
                    statsUserDto.setStartDateStr(DateTimeUtils.getPreviousMonth());
                    statsUserDto.setEndDateStr(DateTimeUtils.getPreviousMonth());
                    statsUserDto.setType(2);
                    statsUserVo = this.findFromStatsUser(statsUserDto);
                    break;
                case 5:
                    //半年
                    statsUserDto.setStartDateStr(DateTimeUtils.getSomeMonthBefore(6));
                    statsUserDto.setEndDateStr(DateTimeUtils.getMonthYM());
                    statsUserDto.setType(2);
                    statsUserVo = this.findFromStatsUser(statsUserDto);

                    thisMonthStatsUserVo = this.getThisMonth(statsUserDto);
                    this.twoStatsUserVoAdd(statsUserVo, thisMonthStatsUserVo);
                    break;
                case 6:
                    //一年
                    statsUserDto.setStartDateStr(DateTimeUtils.getSomeMonthBefore(12));
                    statsUserDto.setEndDateStr(DateTimeUtils.getMonthYM());
                    statsUserDto.setType(2);
                    statsUserVo = this.findFromStatsUser(statsUserDto);

                    thisMonthStatsUserVo = this.getThisMonth(statsUserDto);
                    this.twoStatsUserVoAdd(statsUserVo, thisMonthStatsUserVo);
                    break;
            }
        }
        //全部场地
        List<MerchantStoreVo> merchantStoreVoList = merchantStoreService.findMerchantStoreIdByUserId(statsUserDto.getUserInfo());
        statsUserVo.setMerchantStoreVoList(merchantStoreVoList);
        statsUserVo.setTotalMerchantStore(merchantStoreVoList.size());

        //全部设备
        DeviceDto deviceDto = new DeviceDto();
        deviceDto.setUserInfo(statsUserDto.getUserInfo());
        Integer totalDevice = deviceService.findDeviceCountByUserId(deviceDto);

        statsUserVo.setTotalDevice(totalDevice);

        switch (statsUserDto.getDayType()) {
            case 0:
                statsUserVo.setStartDateStr(DateTimeUtils.getCurrentDateStr());
                statsUserVo.setEndDateStr(DateTimeUtils.getCurrentDateStr());
                break;
            case 3:
                statsUserVo.setStartDateStr(DateTimeUtils.getMonthFirstDay());
                statsUserVo.setEndDateStr(DateTimeUtils.getMonthLastDay());
                break;
            case 4:
                statsUserVo.setStartDateStr(DateTimeUtils.getPreviousMonthFirstDay());
                statsUserVo.setEndDateStr(DateTimeUtils.getPreviousMonthLastDay());
                break;
            case 5:
                statsUserVo.setStartDateStr(DateTimeUtils.getSomeMonthBeforeYMD(6));
                statsUserVo.setEndDateStr(DateTimeUtils.getCurrentDateStr());
                break;
            case 6:
                statsUserVo.setStartDateStr(DateTimeUtils.getSomeMonthBeforeYMD(12));
                statsUserVo.setEndDateStr(DateTimeUtils.getCurrentDateStr());
                break;
            default:
                statsUserVo.setStartDateStr(statsUserDto.getStartDateStr());
                statsUserVo.setEndDateStr(statsUserDto.getEndDateStr());
                break;
        }
        return statsUserVo;
    }

    private StatsUserVo getThisMonth(StatsUserDto statsUserDto) {
        statsUserDto.setStartDateStr(DateTimeUtils.getMonthFirstDay());
        statsUserDto.setEndDateStr(DateTimeUtils.getCurrTime());
        statsUserDto.setType(1);
        StatsUserVo statsUserVo = this.findFromStatsUser(statsUserDto);

        //当天
        StatsUserVo todayStatsUserVo = this.findTodayStatsUserFromOrder(statsUserDto);
        this.twoStatsUserVoAdd(statsUserVo, todayStatsUserVo);

        return statsUserVo;
    }

    private StatsUserVo findFromStatsUser(StatsUserDto statsUserDto) {
        StatsUserVo statsUserVo;

        //子账号单独统计门店
        if (statsUserDto.getUserInfo().getRoleId().equals(RoleEnum.SUB_ACCOUNT.getRoleId())) {
            statsUserVo = statsUserDao.findSubAccountStatsUser(statsUserDto);
            List<StatsPackageUserVo> statistAllPackageList = statsPackageUserDao.findSubAccountStatistPackageUserByUserId(statsUserDto);
            this.typePackage(statistAllPackageList, statsUserVo);
        } else {
            statsUserVo = statsUserDao.findByUserId(statsUserDto);
            List<StatsPackageUserVo> statistAllPackageList = statsPackageUserDao.findCurrentStatistPackageUserByUserId(statsUserDto);
            this.typePackage(statistAllPackageList, statsUserVo);
        }
        //线上出币
        Integer onLineOutCoinTotal = statsUserVo.getOutCoinTotal() - statsUserVo.getOffLinePayOutCoinTotal();
        statsUserVo.setOnLineOutCoinTotal(onLineOutCoinTotal);

        //微信核销总出币 = 微信秒杀核销+微信拼团核销+微信凭证核销
        statsUserVo.setWeiXinVerifyTotalCoin(
                statsUserVo.getWeiXinVoucherOutCoinTotal()
                        +statsUserVo.getWeiXinSeckillOutCoinTotal()
                        +statsUserVo.getWeiXinGroupBuyingOutCoinTotal());

        //活动收入
        BigDecimal activityTurnover = statsUserVo.getSeckillMoney().add(statsUserVo.getGroupBookingMoney()).add(statsUserVo.getConsumptionOfRedEnvelopesMoney()).add(statsUserVo.getMemberOfTheStoredValueMoney());
        statsUserVo.setActivityTurnover(activityTurnover);
        //售币总额 = 游戏币营业额 + 活动营业额 + 抖音核销金额 + 美团核销金额
        statsUserVo.setTurnoverGameCoin(statsUserVo.getTurnoverGameCoin()
                .add(statsUserVo.getTurnoverDouYin())
                .add(statsUserVo.getTurnoverMeiTuan())
                .add(activityTurnover));
        //币均价 = 售币总额 / 售币数
        if(statsUserVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
                statsUserVo.getQuantityOfCoinsSold().compareTo(1) > -1){
            BigDecimal total = statsUserVo.getTurnoverGameCoin().divide(new BigDecimal(statsUserVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
            log.info("平均值保留四位小数："+total);
            statsUserVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
            log.info("四舍五入保留两位小数："+statsUserVo.getAverageCoinPrice());
        }else{
            statsUserVo.setAverageCoinPrice(BigDecimal.ZERO);
        }
        //计算在线支付
        //statsUserVo.setTurnoverOnLine(statsUserVo.getWxMoney().add(statsUserVo.getAliMoney()).subtract(activityTurnover));
        //扫码支付 = 线上扫码 + 线下扫码
        statsUserVo.setScanCodePayTotalTurnover(statsUserVo.getTurnoverOnLine().add(statsUserVo.getTurnoverOfflineCollectionCode()));
        if (statsUserDto.getDayType() <= 1 || statsUserDto.getDayType() == 5) {
            if (statsUserDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                return statsUserVo;
            }
            this.outConPercent(statsUserVo);
            this.amountPercent(statsUserVo);
        }
        return statsUserVo;
    }
    private void amountPercent(StatsUserVo statsUserVo){
        BigDecimal money = new BigDecimal(0);
        statsUserVo.setPercentCashMoney(money);
        statsUserVo.setPercentActivityTurnover(money);
        statsUserVo.setPercentTurnoverOnLine(money);
        statsUserVo.setPercentTurnoverMeiTuan(money);
        statsUserVo.setPercentTurnoverDouYin(money);
        if (statsUserVo.getTurnover().compareTo(BigDecimal.ZERO) > 0) {
            ArrayList<BigDecimal> percentList = new ArrayList<>();
            //现金收款 除以 总营业额 保留两位小数 乘 100
            BigDecimal percentCashMoney = statsUserVo.getCashMoney().divide(statsUserVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsUserVo.setPercentCashMoney(percentCashMoney);
            percentList.add(percentCashMoney);
            // 活动总结算额 除以 总营业额 保留两位小数 乘 100
            BigDecimal activityTurnover1 = statsUserVo.getActivityTurnover().divide(statsUserVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsUserVo.setPercentActivityTurnover(activityTurnover1);
            percentList.add(activityTurnover1);

            // 线上营业额  除以 总营业额 保留两位小数 乘 100
            BigDecimal percentTurnoverOnLine = statsUserVo.getScanCodePayTotalTurnover().divide(statsUserVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsUserVo.setPercentTurnoverOnLine(percentTurnoverOnLine);
            percentList.add(percentTurnoverOnLine);

            //抖音收款
            BigDecimal percentTurnoverDouYin = statsUserVo.getTurnoverDouYin().divide(statsUserVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsUserVo.setPercentTurnoverDouYin(percentTurnoverDouYin);
            percentList.add(percentTurnoverDouYin);

            //美团收款
            BigDecimal percentTurnoverMeiTuan = statsUserVo.getTurnoverMeiTuan().divide(statsUserVo.getTurnover(), 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            statsUserVo.setPercentTurnoverMeiTuan(percentTurnoverMeiTuan);
            percentList.add(percentTurnoverMeiTuan);
            BigDecimal maxPercent = Collections.max(percentList);
            BigDecimal bfb = new BigDecimal(100);
            //0是现金，1是活动...
            Integer index = -1;
            boolean flog = true;
            if(maxPercent.compareTo(BigDecimal.ZERO) == 1){
                for(int i = 0; i < percentList.size(); i++){
                    if(percentList.get(i).compareTo(maxPercent) == 0 && flog){
                        //记录最大百分比坐标
                        index = i;
                        flog = false;
                        continue;
                    }
                    bfb = bfb.subtract(percentList.get(i));
                }
                switch (index){
                    case 0:
                        statsUserVo.setPercentCashMoney(bfb);
                        break;
                    case 1:
                        statsUserVo.setPercentActivityTurnover(bfb);
                        break;
                    case 2:
                        statsUserVo.setPercentTurnoverOnLine(bfb);
                        break;
                    case 3:
                        statsUserVo.setPercentTurnoverDouYin(bfb);
                        break;
                    case 4:
                        statsUserVo.setPercentTurnoverMeiTuan(bfb);
                        break;
                }
            }
        }
    }
    private void typePackage(List<StatsPackageUserVo> statistAllPackageList, StatsUserVo statsUserVo) {
        //门店套餐
        List<StatsUserVo> statistStoreList = new ArrayList<>();
        //抖音套餐
        List<StatsUserVo> statistDouYinPackageList = new ArrayList<>();
        //美团套餐
        List<StatsUserVo> statistMeiTuanPackageList = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(statistAllPackageList)) {
            for (StatsPackageUserVo s : statistAllPackageList) {
                //门店套餐
                if (s.getPackageType().compareTo(StatsPackageStorePackageTypeEnum.STORE_PACKAGE.getCode()) == 0) {
                    StatsUserVo statsUserVo1 = new StatsUserVo();
                    statsUserVo1.setTitle(s.getTitle());
                    statsUserVo1.setStoreDealCount(s.getPayCount());
                    statsUserVo1.setStoreDealMoney(s.getTotalAmount());
                    statistStoreList.add(statsUserVo1);
                } else if (s.getPackageType().compareTo(StatsPackageStorePackageTypeEnum.DOUYIN_PACKAGE.getCode()) == 0) {
                    StatsUserVo statsUserVo1 = new StatsUserVo();
                    statsUserVo1.setTitle(s.getTitle());
                    statsUserVo1.setDouYinDealCount(s.getPayCount());
                    statsUserVo1.setDouYinDealMoney(s.getTotalAmount());
                    statistDouYinPackageList.add(statsUserVo1);
                } else {
                    StatsUserVo statsUserVo1 = new StatsUserVo();
                    statsUserVo1.setTitle(s.getTitle());
                    statsUserVo1.setMeiTuanDealCount(s.getPayCount());
                    statsUserVo1.setMeiTuanDealMoney(s.getTotalAmount());
                    statistMeiTuanPackageList.add(statsUserVo1);
                }
            }
        }
        //分套餐类型
        statsUserVo.setStatistStorePackageList(statistStoreList);
    }

    /**
     * 查找当天的统计
     *
     * @param statsUserDto
     * @return
     */
    private StatsUserVo findTodayStatsUserFromOrder(StatsUserDto statsUserDto) {
        if(ObjectUtils.isNotEmpty(statsUserDto.getHour())){
            //获取昨天的开始时间和结束时间 格式yyyy-MM-dd HH:mm:ss
            statsUserDto.setStartTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.START_DATETIME_FORMATTER));
            statsUserDto.setEndTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.END_DATETIME_FORMATTER));
        }else{
            statsUserDto.setStartTime(DateTimeUtils.getTodayStartTime());
            statsUserDto.setEndTime(DateTimeUtils.getTodayEndTime());
        }
        StatsUserVo statsUserVo = statsUserDao.findOrderStatistics(statsUserDto);


        // 游戏币营业额，通用商品营业额，套票商品营业额
        StatsUserVo statsUserVo1 = statsUserDao.findCommodityTypeTurnover(statsUserDto);
        if (ObjectUtils.isNotEmpty(statsUserVo)) {

        } else {
            statsUserVo.setOutCoinTotal(0);
            statsUserVo.setOnLineOutCoinTotal(0);
            statsUserVo.setOnLinePayOutCoinTotal(0);
            statsUserVo.setOffLinePayOutCoinTotal(0);
            statsUserVo.setInsertCoinTotal(0);
            statsUserVo.setInsertCoinOnLine(0);
            statsUserVo.setInsertCoinOffline(0);
            statsUserVo.setFetchMemberOutCoinTotal(0);
            statsUserVo.setMeiTuanOutCoinTotal(0);
            statsUserVo.setDouYinOutCoinTotal(0);
            statsUserVo.setWeiXinSeckillOutCoinTotal(0);
            statsUserVo.setWeiXinGroupBuyingOutCoinTotal(0);
            statsUserVo.setWeiXinVoucherOutCoinTotal(0);
            statsUserVo.setArtificialOutCoinTotal(0);
            statsUserVo.setWeiXinVerifyTotalCoin(0);
            statsUserVo.setGameCoinRedPacketCoinTotal(0);
            statsUserVo.setGroupBenefitCoinTotal(0);
            statsUserVo.setDistributeBenefitCoinTotal(0);
            statsUserVo.setQuantityOfCoinsSold(0);
            statsUserVo.setAmountOfCoinsConsumed(0);
            statsUserVo.setRemainingCoins(0);
            statsUserVo.setGameCoinRedPacketCoinTotal(0);
            statsUserVo.setGroupBenefitCoinTotal(0);
            statsUserVo.setDistributeBenefitCoinTotal(0);
            statsUserVo.setQuantityOfCoinsSold(0);
            statsUserVo.setAmountOfCoinsConsumed(0);
            statsUserVo.setRemainingCoins(0);
            statsUserVo.setTurnoverOfflineCollectionCode(BigDecimal.ZERO);
            statsUserVo.setStoredValueComplimentaryBalance(BigDecimal.ZERO);
            statsUserVo.setStoredValueRechargeBalance(BigDecimal.ZERO);
            statsUserVo.setConsumeComplimentaryBalance(BigDecimal.ZERO);
            statsUserVo.setConsumeRechargeBalance(BigDecimal.ZERO);
        }
        //门店套餐
        List<StatsUserVo> statistStorePackageList = statsUserDao.findOrderStatistStorePackage(statsUserDto);
        statsUserVo.setStatistStorePackageList(statistStorePackageList);



        //活动
        StatsUserVo activityStatsUser = statsUserDao.findActivityMoney(statsUserDto);
        statsUserVo.setActivityTurnover(activityStatsUser.getActivityTurnover());

        //售币总额 = 游戏币营业额 + 活动营业额 + 抖音核销金额 + 美团核销金额
        statsUserVo.setTurnoverGameCoin(
                statsUserVo1.getTurnoverGameCoin()
                .add(statsUserVo.getTurnoverDouYin())
                .add(statsUserVo.getTurnoverMeiTuan())
                .add(activityStatsUser.getActivityTurnover()));
        //币均价 = 售币总额 / 售币数
        if(statsUserVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
            statsUserVo.getQuantityOfCoinsSold().compareTo(1) > -1){
            BigDecimal total = statsUserVo.getTurnoverGameCoin().divide(new BigDecimal(statsUserVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
            log.info("平均值保留四位小数："+total);
            statsUserVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
            log.info("四舍五入保留两位小数："+statsUserVo.getAverageCoinPrice());
        }else{
            statsUserVo.setAverageCoinPrice(BigDecimal.ZERO);
        }

        //TODO 注意：现金笔数、抖音核销笔数、美团核销笔数先不按memberId为空的来计算，后期需求再优化

        // 消费新顾客数
        Integer newNum = memberStoreBalanceService.findDayMemberNewNumByUserId(statsUserDto);
        // 现金笔数 + 抖音核销笔数 + 美团核销笔数
        statsUserVo.setMemberConsumeNewNum(
                newNum +
                        statsUserVo.getCashCount() +
                        statsUserVo.getMeiTuanCount() +
                        statsUserVo.getDouYinCount()
        );
        // 消费老顾客数
        Integer oldNum = memberStoreBalanceService.findDayMemberOldNumByUserId(statsUserDto);
        statsUserVo.setMemberConsumeOldNum(oldNum);
        //消费顾客 消费新顾客数 + 消费老顾客数。
        statsUserVo.setMemberConsumeNum(statsUserVo.getMemberConsumeNewNum() + statsUserVo.getMemberConsumeOldNum());

        //最高客单价
        Integer max = statsUserVo.getMaxTotalAmount().compareTo(activityStatsUser.getMaxTotalAmount());
        statsUserVo.setMaximumUnitPrice(max < 0 ? activityStatsUser.getMaxTotalAmount() : statsUserVo.getMaxTotalAmount());
        //最低客单价
        Integer min = statsUserVo.getMinTotalAmount().compareTo(activityStatsUser.getMinTotalAmount());
        statsUserVo.setMiniimumUnitPrice(min < 0 ? activityStatsUser.getMinTotalAmount() : statsUserVo.getMinTotalAmount());
        //平均客价
        if (statsUserVo.getTurnover().compareTo(BigDecimal.ZERO) > 0 && statsUserVo.getMemberConsumeNum() > 0) {
            statsUserVo.setAveragePrice(statsUserVo.getTurnover().divide(BigDecimal.valueOf(statsUserVo.getMemberConsumeNum()), 2, BigDecimal.ROUND_HALF_UP));
        } else {
            statsUserVo.setAveragePrice(BigDecimal.ZERO);
        }
        //留存手机号会员数量
        Integer countPhoneNumber = memberDao.findCountByMemberId(statsUserDto);
        statsUserVo.setLeaveMemberPhoneNumber(countPhoneNumber);

        //累计营业额
        statsUserVo.setTurnover(statsUserVo.getTurnover().add(statsUserVo.getActivityTurnover()));
        //累计在线支付
        //statsUserVo.setTurnoverOnLine(statsUserVo.getWxMoney().add(statsUserVo.getAliMoney()));
        //累计结算额
        statsUserVo.setSettlementMoney(statsUserVo.getSettlementMoney().add(activityStatsUser.getActivitySettlementMoney()));


        //计算出币的占比
        //dayType：0当天 1昨天（夜间统计的时候点击昨天调用实时统计也要算百分比）
        if (statsUserDto.getDayType() == 0 || statsUserDto.getDayType() == 1){
            this.outConPercent(statsUserVo);
            this.amountPercent(statsUserVo);
        }
        return statsUserVo;
    }

    //计算币占比
    private void outConPercent(StatsUserVo statsUserVo) {
        //初始化
        BigDecimal rate = new BigDecimal(0);
        statsUserVo.setPercentOffLinePayOutCoin(rate);
        statsUserVo.setPercentFetchMemberOutCoin(rate);
        statsUserVo.setPercentOnLinePayOutCoinTotal(rate);
        statsUserVo.setPercentOnLinePayOutCoinTotal(rate);
        statsUserVo.setPercentArtificialOutCoin(rate);
        statsUserVo.setPercentMeiTuanOutCoin(rate);
        statsUserVo.setPercentDouYinOutCoin(rate);
        statsUserVo.setPercentWeiXinVerifyOutCoin(rate);
        statsUserVo.setPercentInsertCoinOffline(rate);
        statsUserVo.setPercentInsertCoinOnLine(rate);
        statsUserVo.setPercentDistributeBenefitCoin(rate);
        statsUserVo.setPercentCoinRedPacketCoin(rate);
        //购币情况
        if(statsUserVo.getQuantityOfCoinsSold() > 0){
            //BigDecimal total = new BigDecimal(statsUserVo.getOutCoinTotal());
            BigDecimal total = new BigDecimal(statsUserVo.getQuantityOfCoinsSold());
            // 现金出币 除以 总出币 保留两位小数 乘 100
            BigDecimal offLinePayOutCoinTotal = new BigDecimal(statsUserVo.getOffLinePayOutCoinTotal());
            BigDecimal offLinePayOutCoinTotalRate = offLinePayOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentOffLinePayOutCoin(offLinePayOutCoinTotalRate.multiply(new BigDecimal("100")));

            //线上出币
            BigDecimal linePayOutCoinTotal = new BigDecimal(statsUserVo.getOnLinePayOutCoinTotal());
            BigDecimal linePayOutCoinTotalRate = linePayOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentOnLinePayOutCoinTotal(linePayOutCoinTotalRate.multiply(new BigDecimal("100")));

            //会员取币
            BigDecimal fetchMemberOutCoinTotal = new BigDecimal(statsUserVo.getFetchMemberOutCoinTotal());
            BigDecimal fetchMemberOutCoinTotalRate = fetchMemberOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentFetchMemberOutCoin(fetchMemberOutCoinTotalRate.multiply(new BigDecimal("100")));

            //抖音核销出币
            BigDecimal douYinOutCoinTotal = new BigDecimal(statsUserVo.getDouYinOutCoinTotal());
            BigDecimal douYinOutCoinTotalRate = douYinOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentDouYinOutCoin(douYinOutCoinTotalRate.multiply(new BigDecimal("100")));

            //美团核销出币
            BigDecimal meiTuanOutCoinTotal = new BigDecimal(statsUserVo.getMeiTuanOutCoinTotal());
            BigDecimal meiTuanOutCoinTotalRate = meiTuanOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentMeiTuanOutCoin(meiTuanOutCoinTotalRate.multiply(new BigDecimal("100")));

            //微信核销出币
            BigDecimal weiXinVerifyOutCoinTotal = new BigDecimal(statsUserVo.getWeiXinVerifyTotalCoin());
            BigDecimal weiXinVerifyOutCoinTotalRate = weiXinVerifyOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentWeiXinVerifyOutCoin(weiXinVerifyOutCoinTotalRate.multiply(new BigDecimal("100")));

            //人工出币
            BigDecimal artificialOutCoinTotal = new BigDecimal(statsUserVo.getArtificialOutCoinTotal());
            BigDecimal artificialOutCoinTotalRate = artificialOutCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentArtificialOutCoin(artificialOutCoinTotalRate.multiply(new BigDecimal("100")));

            //游戏币红包币
            BigDecimal gameCoinRedPacketCoinTotal = new BigDecimal(statsUserVo.getGameCoinRedPacketCoinTotal());
            BigDecimal gameCoinRedPacketCoinTotalRate = gameCoinRedPacketCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentCoinRedPacketCoin(gameCoinRedPacketCoinTotalRate.multiply(new BigDecimal("100")));
            //加群福利币
            BigDecimal groupBenefitCoinTotal = new BigDecimal(statsUserVo.getGroupBenefitCoinTotal());
            BigDecimal groupBenefitCoinTotalRate = groupBenefitCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentGroupBenefitCoin(groupBenefitCoinTotalRate.multiply(new BigDecimal("100")));

            //派发福利币
            BigDecimal distributeBenefitCoinTotal = new BigDecimal(statsUserVo.getDistributeBenefitCoinTotal());
            BigDecimal distributeBenefitCoinTotalRate = distributeBenefitCoinTotal.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentDistributeBenefitCoin(distributeBenefitCoinTotalRate.multiply(new BigDecimal("100")));

        }

        //投币情况
        if(statsUserVo.getInsertCoinTotal() > 0){
            BigDecimal total = new BigDecimal(statsUserVo.getInsertCoinTotal());
            //线上投币
            BigDecimal insertCoinOnLine = new BigDecimal(statsUserVo.getInsertCoinOnLine());
            BigDecimal insertCoinOnLineRate = insertCoinOnLine.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentInsertCoinOnLine(insertCoinOnLineRate.multiply(new BigDecimal("100")));

            //线下投币
            BigDecimal insertCoinOffline = new BigDecimal(statsUserVo.getInsertCoinOffline());
            BigDecimal insertCoinOfflineRate = insertCoinOffline.divide(total, 2, BigDecimal.ROUND_HALF_UP);
            statsUserVo.setPercentInsertCoinOffline(insertCoinOfflineRate.multiply(new BigDecimal("100")));
        }
    }

    private void twoStatsUserVoAdd(StatsUserVo statsUserVo, StatsUserVo statsUserVo2) {
        //门店套餐累加
        if (ObjectUtils.isNotEmpty(statsUserVo.getStatistStorePackageList()) &&
                ObjectUtils.isNotEmpty(statsUserVo2.getStatistStorePackageList())) {
            //A集合和B集合相同的累加
            statsUserVo.getStatistStorePackageList().forEach(item -> statsUserVo2.getStatistStorePackageList().forEach(data -> {
                if (item.getTitle().equals(data.getTitle())) {
                    item.setStoreDealMoney(item.getStoreDealMoney().add(data.getStoreDealMoney()));
                    item.setStoreDealCount(item.getStoreDealCount() + data.getStoreDealCount());
                }
            }));

            List<StatsUserVo> list = new ArrayList<>();
            list.addAll(statsUserVo.getStatistStorePackageList());
            list.addAll(statsUserVo2.getStatistStorePackageList());
            List<StatsUserVo> arrays = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
                    -> new TreeSet<>(Comparator.comparing(StatsUserVo::getTitle))), ArrayList::new));
            statsUserVo.setStatistStorePackageList(arrays);
        }
        //A集合为空，把B集合的值赋值给A集合
        if (ObjectUtils.isEmpty(statsUserVo.getStatistStorePackageList()) &&
                ObjectUtils.isNotEmpty(statsUserVo2.getStatistStorePackageList())) {
            statsUserVo.setStatistStorePackageList(statsUserVo2.getStatistStorePackageList());
        }
        //排序一下
        if (ObjectUtils.isNotEmpty(statsUserVo.getStatistStorePackageList())) {
            statsUserVo.getStatistStorePackageList().sort(Comparator.comparing(StatsUserVo::getStoreDealMoney, Comparator.reverseOrder()));
        }

        //最高客单价
        Integer max = statsUserVo.getMaxTotalAmount().compareTo(statsUserVo2.getMaxTotalAmount());
        statsUserVo.setMaxTotalAmount(max < 0 ? statsUserVo2.getMaxTotalAmount() : statsUserVo.getMaxTotalAmount());
        //最低客单价
        Integer min = statsUserVo.getMinTotalAmount().compareTo(statsUserVo2.getMinTotalAmount());
        statsUserVo.setMinTotalAmount(min < 0 ? statsUserVo2.getMinTotalAmount() : statsUserVo.getMinTotalAmount());
        statsUserVo.setMemberConsumeNum(statsUserVo2.getMemberConsumeNum() + statsUserVo.getMemberConsumeNum());
        statsUserVo.setMemberConsumeNewNum(statsUserVo2.getMemberConsumeNewNum() + statsUserVo.getMemberConsumeNewNum());
        statsUserVo.setMemberConsumeOldNum(statsUserVo2.getMemberConsumeOldNum() + statsUserVo.getMemberConsumeOldNum());

        statsUserVo.setLeaveMemberPhoneNumber(statsUserVo2.getLeaveMemberPhoneNumber() + statsUserVo.getLeaveMemberPhoneNumber());
        statsUserVo.setTurnover(statsUserVo2.getTurnover().add(statsUserVo.getTurnover()));
        //平均值
        if(statsUserVo.getTurnover().compareTo(BigDecimal.ZERO)>0 && statsUserVo.getMemberConsumeNum() > 0){
            statsUserVo.setAveragePrice(statsUserVo.getTurnover().divide(BigDecimal.valueOf(statsUserVo.getMemberConsumeNum()),2, BigDecimal.ROUND_HALF_UP));
        }else{
            statsUserVo.setAveragePrice(BigDecimal.ZERO);
        }
        //会员出币
        statsUserVo.setFetchMemberOutCoinTotal(statsUserVo2.getFetchMemberOutCoinTotal()+statsUserVo.getFetchMemberOutCoinTotal());
        //抖音核销 出币
        statsUserVo.setDouYinOutCoinTotal(statsUserVo2.getDouYinOutCoinTotal()+statsUserVo.getDouYinOutCoinTotal());
        //美团核销 出币
        statsUserVo.setMeiTuanOutCoinTotal(statsUserVo2.getMeiTuanOutCoinTotal()+statsUserVo.getMeiTuanOutCoinTotal());
        //人工出币
        statsUserVo.setArtificialOutCoinTotal(statsUserVo2.getArtificialOutCoinTotal()+statsUserVo.getArtificialOutCoinTotal());
        //微信秒杀核销
        statsUserVo.setWeiXinSeckillOutCoinTotal(statsUserVo2.getWeiXinSeckillOutCoinTotal()+statsUserVo.getWeiXinSeckillOutCoinTotal());
        //微信拼团核销
        statsUserVo.setWeiXinGroupBuyingOutCoinTotal(statsUserVo2.getWeiXinGroupBuyingOutCoinTotal()+statsUserVo.getWeiXinGroupBuyingOutCoinTotal());
        //微信凭证核销
        statsUserVo.setWeiXinVoucherOutCoinTotal(statsUserVo2.getWeiXinVoucherOutCoinTotal()+statsUserVo.getWeiXinVoucherOutCoinTotal());
        //微信核销总出币
        statsUserVo.setWeiXinVerifyTotalCoin(statsUserVo2.getWeiXinVerifyTotalCoin()+statsUserVo.getWeiXinVerifyTotalCoin());
        //线上出币
        statsUserVo.setOnLinePayOutCoinTotal(statsUserVo2.getOnLinePayOutCoinTotal()+statsUserVo.getOnLinePayOutCoinTotal());
        //游戏红包币
        statsUserVo.setGameCoinRedPacketCoinTotal(statsUserVo2.getGameCoinRedPacketCoinTotal()+statsUserVo.getGameCoinRedPacketCoinTotal());
        //加群福利币
        statsUserVo.setGroupBenefitCoinTotal(statsUserVo2.getGroupBenefitCoinTotal()+statsUserVo.getGroupBenefitCoinTotal());
        //派发福利币
        statsUserVo.setDistributeBenefitCoinTotal(statsUserVo2.getDistributeBenefitCoinTotal()+statsUserVo.getDistributeBenefitCoinTotal());
        //售币数（游戏币销售数量）
        statsUserVo.setQuantityOfCoinsSold(statsUserVo2.getQuantityOfCoinsSold()+statsUserVo.getQuantityOfCoinsSold());
        //出币数（游戏币消耗数量）
        statsUserVo.setAmountOfCoinsConsumed(statsUserVo2.getAmountOfCoinsConsumed()+statsUserVo.getAmountOfCoinsConsumed());
        //余币数 = 售币数-消耗数
        statsUserVo.setRemainingCoins(statsUserVo.getQuantityOfCoinsSold()-statsUserVo.getAmountOfCoinsConsumed());
        //游戏币营业额
        statsUserVo.setTurnoverGameCoin(statsUserVo2.getTurnoverGameCoin().add(statsUserVo.getTurnoverGameCoin()));
        //币均价 = 售币总额 / 售币数
        if(statsUserVo.getTurnoverGameCoin().compareTo(BigDecimal.ONE) > -1 &&
                statsUserVo.getQuantityOfCoinsSold().compareTo(1) > -1){
            BigDecimal total = statsUserVo.getTurnoverGameCoin().divide(new BigDecimal(statsUserVo.getQuantityOfCoinsSold()), 4, BigDecimal.ROUND_HALF_UP);
            log.info("平均值保留四位小数："+total);
            statsUserVo.setAverageCoinPrice(total.setScale(2, BigDecimal.ROUND_HALF_UP));
            log.info("四舍五入保留两位小数："+statsUserVo.getAverageCoinPrice());
        }else{
            statsUserVo.setAverageCoinPrice(BigDecimal.ZERO);
        }
        statsUserVo.setSettlementMoney(statsUserVo2.getSettlementMoney().add(statsUserVo.getSettlementMoney()));
        statsUserVo.setCashMoney(statsUserVo2.getCashMoney().add(statsUserVo.getCashMoney()));
        statsUserVo.setTurnoverOnLine(statsUserVo2.getTurnoverOnLine().add(statsUserVo.getTurnoverOnLine()));
        statsUserVo.setActivityTurnover(statsUserVo2.getActivityTurnover().add(statsUserVo.getActivityTurnover()));
        statsUserVo.setOutCoinTotal(statsUserVo2.getOutCoinTotal() + statsUserVo.getOutCoinTotal());
        statsUserVo.setOnLineOutCoinTotal(statsUserVo2.getOnLineOutCoinTotal() + statsUserVo.getOnLineOutCoinTotal());
        statsUserVo.setOffLinePayOutCoinTotal(statsUserVo2.getOffLinePayOutCoinTotal() + statsUserVo.getOffLinePayOutCoinTotal());
        statsUserVo.setInsertCoinTotal(statsUserVo2.getInsertCoinTotal() + statsUserVo.getInsertCoinTotal());
        statsUserVo.setInsertCoinOnLine(statsUserVo2.getInsertCoinOnLine() + statsUserVo.getInsertCoinOnLine());
        statsUserVo.setInsertCoinOffline(statsUserVo2.getInsertCoinOffline() + statsUserVo.getInsertCoinOffline());
        statsUserVo.setGiftConsume(statsUserVo2.getGiftConsume() + statsUserVo.getGiftConsume());
        statsUserVo.setGiftCost(statsUserVo2.getGiftCost().add(statsUserVo.getGiftCost()));
        statsUserVo.setGiftOutRate(statsUserVo2.getGiftOutRate().add(statsUserVo.getGiftOutRate()));
        statsUserVo.setIncomeCommodityTotal(statsUserVo2.getIncomeCommodityTotal() + statsUserVo.getIncomeCommodityTotal());
        statsUserVo.setIncomeTotalIntegral(statsUserVo2.getIncomeTotalIntegral() + statsUserVo.getIncomeTotalIntegral());
        statsUserVo.setExpendCommodityTotal(statsUserVo2.getExpendCommodityTotal() + statsUserVo.getExpendCommodityTotal());
        statsUserVo.setExpendTotalIntegral(statsUserVo2.getExpendTotalIntegral() + statsUserVo.getExpendTotalIntegral());
        statsUserVo.setTurnoverDouYin(statsUserVo2.getTurnoverDouYin().add(statsUserVo.getTurnoverDouYin()));
        statsUserVo.setTurnoverMeiTuan(statsUserVo2.getTurnoverMeiTuan().add(statsUserVo.getTurnoverMeiTuan()));
        statsUserVo.setScanCodePayTotalTurnover(statsUserVo2.getScanCodePayTotalTurnover().add(statsUserVo.getScanCodePayTotalTurnover()));
        statsUserVo.setTiktokCancellationFee(statsUserVo2.getTiktokCancellationFee().add(statsUserVo.getTiktokCancellationFee()));
        statsUserVo.setMeiTuanCancellationFee(statsUserVo2.getMeiTuanCancellationFee().add(statsUserVo.getMeiTuanCancellationFee()));
        statsUserVo.setScanningFee(statsUserVo2.getScanningFee().add(statsUserVo.getScanningFee()));
        statsUserVo.setIncomeTotalGameCoin(statsUserVo2.getIncomeTotalGameCoin() +statsUserVo.getIncomeTotalGameCoin() );
        statsUserVo.setIncomeTotalLottery(statsUserVo2.getIncomeTotalLottery() + statsUserVo.getIncomeTotalLottery());
        statsUserVo.setIncomeCommodityGameCoin(statsUserVo2.getIncomeCommodityGameCoin() + statsUserVo.getIncomeCommodityGameCoin());
        statsUserVo.setIncomeCommodityLottery(statsUserVo2.getIncomeCommodityLottery() + statsUserVo.getIncomeCommodityLottery());

        statsUserVo.setStoredValueRechargeBalance(statsUserVo2.getStoredValueRechargeBalance().add(statsUserVo.getStoredValueRechargeBalance()));
        statsUserVo.setStoredValueComplimentaryBalance(statsUserVo2.getStoredValueComplimentaryBalance().add(statsUserVo.getStoredValueRechargeBalance()));
        statsUserVo.setConsumeRechargeBalance(statsUserVo2.getConsumeRechargeBalance().add(statsUserVo.getStoredValueRechargeBalance()));
        statsUserVo.setConsumeComplimentaryBalance(statsUserVo2.getConsumeComplimentaryBalance().add(statsUserVo.getStoredValueRechargeBalance()));
        this.outConPercent(statsUserVo);
        this.amountPercent(statsUserVo);
    }

    //套票核销数据合并
    private List<StatsUserVo> mergeTicketUsageData(List<StatsUserVo> statistTicketUsageRecordList, List<StatsUserVo> statistTicketUsageRecordList1) {
        // 创建一个 HashMap 用于存储设备数据，键为设备编号
        Map<String, StatsUserVo> deviceMap = new HashMap<>();

        // 处理今天的数据
        for (StatsUserVo data : statistTicketUsageRecordList) {
            // 将今天的套票核销添加到 Map 中
            // 生成唯一的key：commodityId_commodityStoreUpDownId_commodityProjectUpDownId
            StringBuffer key = new StringBuffer();
            key.append(data.getCommodityId()).append("_")
                    .append(data.getCommodityStoreUpDownId()).append("_")
                    .append(data.getCommodityProjectUpDownId());
            deviceMap.put(key.toString(), data);
        }

        // 处理昨天的数据
        for (StatsUserVo data : statistTicketUsageRecordList1) {
            // 合并昨天的数据
            StringBuffer key = new StringBuffer();
            key.append(data.getCommodityId()).append("_")
                    .append(data.getCommodityStoreUpDownId()).append("_")
                    .append(data.getCommodityProjectUpDownId());
            deviceMap.merge(key.toString(), data, (existing, newData) -> {
                // 新建一个 ，更新收入为现有收入与新数据收入之和
                int combinedNum = existing.getTotalTime() + newData.getTotalTime();
                data.setTotalTime(combinedNum);
                return data;
            });
        }

        // 将合并后的结果转换为列表并返回
        return new ArrayList<>(deviceMap.values());
    }


    @Override
    public BigDecimal findThisMonthTurnover(StatsUserDto statsUserDto) {
        statsUserDto.setStartDateStr(DateTimeUtils.getMonthFirstDay());
        statsUserDto.setEndDateStr(DateTimeUtils.getMonthLastDay());
        statsUserDto.setStatsType(StatsTypeEnum.statsUser.getCode());
        return statsUserDao.findThisMonthTurnover(statsUserDto);
    }

    @Override
    public List<StatsUserVo> findByDateStore(StatsUserDto statsUserDto) {
        return statsUserDao.findByDateStore(statsUserDto);
    }

    /**
     * 统计活动订单营业额
     *
     * @param statsUserDto
     * @return
     */
    @Override
    public StatsUserVo findActivityMoney(StatsUserDto statsUserDto) {
        return statsUserDao.findActivityMoney(statsUserDto);
    }

    /**
     * 运营统计分支，点击 投币，出币，收入，消耗礼品等进入详情
     *
     * @param statsUserDto
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    @Override
    public ServerResponse findStatsBranchHead(StatsUserDto statsUserDto) throws ExecutionException, InterruptedException {

        /**
         * 头部统计
         *      判断包含今天
         *          统计今天
         *
         *      统计其他时间段
         *
         * 列表展示
         *      按时间段查询
         */

        if (StringUtils.isEmpty(statsUserDto.getBranchId())) {
            return ServerResponse.createByErrorMessage("分支统计ID不能为空");
        }

        if (StringUtils.isEmpty(statsUserDto.getStartDateStr())) {
            return ServerResponse.createByErrorMessage("开始时间不能为空");
        }

        if (StringUtils.isEmpty(statsUserDto.getEndDateStr())) {
            return ServerResponse.createByErrorMessage("结束时间不能为空");
        }

        CompletableFuture<StatsUserVo> todayFuture = CompletableFuture.supplyAsync(() -> {
            StatsUserVo todayStatsUserVo = new StatsUserVo();
            todayStatsUserVo.setCashMoney(BigDecimal.ZERO);

            // 现金各面额张数
            todayStatsUserVo.setOneYuanDenomination(0);
            todayStatsUserVo.setFiveYuanDenomination(0);
            todayStatsUserVo.setTenYuanDenomination(0);
            todayStatsUserVo.setTwentyYuanDenomination(0);
            todayStatsUserVo.setFiftyYuanDenomination(0);
            todayStatsUserVo.setOneHundredYuanDenomination(0);

            // 计算每个面额的总额：1元 * 1张 = 1元
            todayStatsUserVo.setOneYuanDenominationTotal(BigDecimal.ZERO);
            todayStatsUserVo.setFiveYuanDenominationTotal(BigDecimal.ZERO);
            todayStatsUserVo.setTenYuanDenominationTotal(BigDecimal.ZERO);
            todayStatsUserVo.setTwentyYuanDenominationTotal(BigDecimal.ZERO);
            todayStatsUserVo.setFiftyYuanDenominationTotal(BigDecimal.ZERO);
            todayStatsUserVo.setOneHundredYuanDenominationTotal(BigDecimal.ZERO);

            todayStatsUserVo.setTurnoverOnLine(BigDecimal.ZERO);
            todayStatsUserVo.setActivityTurnover(BigDecimal.ZERO);

            todayStatsUserVo.setOutCoinTotal(0);
            todayStatsUserVo.setOnLineOutCoinTotal(0);
            todayStatsUserVo.setOnLinePayOutCoinTotal(0);
            todayStatsUserVo.setOffLinePayOutCoinTotal(0);
            //会员取币
            todayStatsUserVo.setFetchMemberOutCoinTotal(0);
            todayStatsUserVo.setDouYinOutCoinTotal(0);
            todayStatsUserVo.setMeiTuanOutCoinTotal(0);
            todayStatsUserVo.setArtificialOutCoinTotal(0);
            todayStatsUserVo.setWeiXinSeckillOutCoinTotal(0);
            todayStatsUserVo.setWeiXinGroupBuyingOutCoinTotal(0);
            todayStatsUserVo.setWeiXinVoucherOutCoinTotal(0);
            todayStatsUserVo.setWeiXinVerifyTotalCoin(0);
            todayStatsUserVo.setInsertCoinTotal(0);
            todayStatsUserVo.setInsertCoinOffline(0);
            todayStatsUserVo.setInsertCoinOnLine(0);
            todayStatsUserVo.setGameCoinRedPacketCoinTotal(0);
            todayStatsUserVo.setGroupBenefitCoinTotal(0);
            todayStatsUserVo.setDistributeBenefitCoinTotal(0);

            //出礼总数
            todayStatsUserVo.setTuiLiIncrementTotal(0);
            todayStatsUserVo.setGiftConsume(0);

            //营业额
            todayStatsUserVo.setTurnover(BigDecimal.ZERO);
            //抖音收入
            todayStatsUserVo.setTurnoverDouYin(BigDecimal.ZERO);
            //美团收入
            todayStatsUserVo.setTurnoverMeiTuan(BigDecimal.ZERO);
            todayStatsUserVo.setActivityUnwrittenMoney(BigDecimal.ZERO);
            todayStatsUserVo.setActivityCancelledMoney(BigDecimal.ZERO);
            todayStatsUserVo.setManualTerminalCash(BigDecimal.ZERO);
            todayStatsUserVo.setSelfServiceTerminalCash(BigDecimal.ZERO);
            todayStatsUserVo.setScanCodePayTotalTurnover(BigDecimal.ZERO);
            todayStatsUserVo.setTurnoverOfflineCollectionCode(BigDecimal.ZERO);
            try {
                LocalDateTime now = LocalDateTime.now();
                // 获取当前小时（24小时制）凌晨0点到六点前，调用今日统计的数据
                int hour = now.getHour();
                log.info("时间是否为凌晨0点到6点："+hour);
                // 不包含今天数据：除了昨天时间（0点到6点）和 上月时间 自定义时间有可能不包含今天数据
                if (!DateTimeUtils.getCurrTime().equals(statsUserDto.getEndDateStr())
                    && ((hour > 5 && statsUserDto.getDateType().compareTo(1)==0)) ||
                        statsUserDto.getDateType().compareTo(5)==0 ||
                        (statsUserDto.getDateType().compareTo(-1)==0 &&
                                !DateTimeUtils.getCurrTime().equals(statsUserDto.getEndDateStr()))) {
                    log.info("不调用实时查询数据");
                    return todayStatsUserVo;
                }

                // 组装查当天的条件参数
                StatsUserDto conditionStatsUserDto = new StatsUserDto();
                conditionStatsUserDto.setUserInfo(statsUserDto.getUserInfo());
                if(hour >= 0 && hour <= 5 && statsUserDto.getDateType().compareTo(1) == 0){
                    //获取昨天的开始时间和结束时间 格式yyyy-MM-dd HH:mm:ss
                    conditionStatsUserDto.setStartTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.START_DATETIME_FORMATTER));
                    conditionStatsUserDto.setEndTime(DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.END_DATETIME_FORMATTER));
                }else{
                    conditionStatsUserDto.setStartTime(DateTimeUtils.getTodayStartTime());
                    conditionStatsUserDto.setEndTime(DateTimeUtils.getTodayEndTime());
                }
                conditionStatsUserDto.setMerchantStoreIdArray(statsUserDto.getMerchantStoreIdArray());
                conditionStatsUserDto.setDeviceNo(statsUserDto.getDeviceNo());
                if (BranchIdEnum.CASH_INCOME.getId().compareTo(statsUserDto.getBranchId()) == 0) {
                    // 现金
                    StatsUserVo cashMoneyStatsUserVo = statsUserDao.findOrderStatistics(conditionStatsUserDto);
                    // 保存现金总数
                    todayStatsUserVo.setCashMoney(cashMoneyStatsUserVo.getCashMoney());
                    // 吧台现金总数
                    todayStatsUserVo.setManualTerminalCash(cashMoneyStatsUserVo.getManualTerminalCash());
                    //超级兑币机现金总数
                    todayStatsUserVo.setSelfServiceTerminalCash(cashMoneyStatsUserVo.getSelfServiceTerminalCash());

                    // 去order表统计各个面额的张数 兑币机
                    List<OrderVo> orderDenominationList = orderService.findDenominationCountByPermission(conditionStatsUserDto.getUserInfo(), statsUserDto.getMerchantStoreIdArray(), conditionStatsUserDto.getStartTime(), conditionStatsUserDto.getEndTime());
                    log.info("全部数据："+JSON.toJSONString(orderDenominationList));
                    //有几台 兑币机
                    List<OrderVo> arrayDeviceNo =
                            orderDenominationList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
                                    -> new TreeSet<>(Comparator.comparing(OrderVo::getDeviceNo))), ArrayList::new));
                    List<StatsStoreVo> orderDeviceNoList = new ArrayList<>();
                    for (OrderVo orderVo : arrayDeviceNo) {
                        StatsStoreVo ov = new StatsStoreVo();
                        ov.setOneYuanDenomination(0);
                        ov.setFiveYuanDenomination(0);
                        ov.setTenYuanDenomination(0);
                        ov.setTwentyYuanDenomination(0);
                        ov.setFiftyYuanDenomination(0);
                        ov.setOneHundredYuanDenomination(0);
                        BigDecimal total = BigDecimal.ZERO;
                        for (OrderVo vo : orderDenominationList) {
                            if(vo.getDeviceNo().equals(orderVo.getDeviceNo())){
                                total = total.add(vo.getSelfServiceTerminalCash());
                                if(BigDecimal.ONE.compareTo(vo.getTotalAmount()) == 0){
                                    ov.setOneYuanDenomination(vo.getTotalCount());
                                }else if(BigDecimal.valueOf(5).compareTo(vo.getTotalAmount()) == 0){
                                    ov.setFiveYuanDenomination(vo.getTotalCount());
                                }else if(BigDecimal.TEN.compareTo(vo.getTotalAmount()) == 0){
                                    ov.setTenYuanDenomination(vo.getTotalCount());
                                }else if(BigDecimal.valueOf(20).compareTo(vo.getTotalAmount()) == 0){
                                    ov.setTwentyYuanDenomination(vo.getTotalCount());
                                }else if(BigDecimal.valueOf(50).compareTo(vo.getTotalAmount()) == 0){
                                    ov.setFiftyYuanDenomination(vo.getTotalCount());
                                }else if(BigDecimal.valueOf(100).compareTo(vo.getTotalAmount()) == 0){
                                    ov.setOneHundredYuanDenomination(vo.getTotalCount());
                                }
                            }
                        }
                        ov.setDeviceTypeName(orderVo.getDeviceTypeName());
                        ov.setDeviceNo(orderVo.getDeviceNo());
                        ov.setDeviceAlias(orderVo.getDeviceAlias());
                        ov.setSelfServiceTerminalCash(total);
                        orderDeviceNoList.add(ov);
                    }
                    orderDeviceNoList.forEach(data -> {
                        // 计算每个面额的总额：1元 * 1张 = 1元
                        data.setOneYuanDenominationTotal(BigDecimal.ONE.multiply(BigDecimal.valueOf(data.getOneYuanDenomination())));
                        data.setFiveYuanDenominationTotal(BigDecimal.valueOf(5).multiply(BigDecimal.valueOf(data.getFiveYuanDenomination())));
                        data.setTenYuanDenominationTotal(BigDecimal.TEN.multiply(BigDecimal.valueOf(data.getTenYuanDenomination())));
                        data.setTwentyYuanDenominationTotal(BigDecimal.valueOf(20).multiply(BigDecimal.valueOf(data.getTwentyYuanDenomination())));
                        data.setFiftyYuanDenominationTotal(BigDecimal.valueOf(50).multiply(BigDecimal.valueOf(data.getFiftyYuanDenomination())));
                        data.setOneHundredYuanDenominationTotal(BigDecimal.valueOf(100).multiply(BigDecimal.valueOf(data.getOneHundredYuanDenomination())));
                    });
                    todayStatsUserVo.setStatsStoreDeviceNoList(orderDeviceNoList);
                    log.info("兑币机："+JSON.toJSONString(todayStatsUserVo.getStatsStoreDeviceNoList()));
                } else if (BranchIdEnum.ONLINE_REVENUE.getId().compareTo(statsUserDto.getBranchId()) == 0) {
                    // 在线支付
                    StatsUserVo onlineStatsUserVo = statsUserDao.findOrderStatistics(conditionStatsUserDto);
                    todayStatsUserVo.setTurnoverOnLine(onlineStatsUserVo.getTurnoverOnLine());
//                    todayStatsUserVo.setTurnoverOnLine(onlineStatsUserVo.getWxMoney().add(onlineStatsUserVo.getAliMoney()));
                    todayStatsUserVo.setScanCodePayTotalTurnover(todayStatsUserVo.getTurnoverOnLine().add(onlineStatsUserVo.getTurnoverOfflineCollectionCode()));
                    todayStatsUserVo.setTurnoverOfflineCollectionCode(onlineStatsUserVo.getTurnoverOfflineCollectionCode());
                } else if (BranchIdEnum.ACTIVITY_REVENUE.getId().compareTo(statsUserDto.getBranchId()) == 0) {
                    // 活动收入
                    StatsUserVo activityStatsUserVo = statsUserDao.findActivityMoney(conditionStatsUserDto);
                    //未核销
                    todayStatsUserVo.setActivityUnwrittenMoney(activityStatsUserVo.getActivityUnwrittenMoney());
                    //已核销金额
                    StatsUserVo activityStatsUserVo1 = statsUserDao.findActivityActivityCancelledMoney(conditionStatsUserDto);
                    if(activityStatsUserVo1 == null){
                        activityStatsUserVo1 = new StatsUserVo();
                        activityStatsUserVo1.setActivityCancelledMoney(BigDecimal.ZERO);
                    }
                    todayStatsUserVo.setActivityCancelledMoney(activityStatsUserVo1.getActivityCancelledMoney().add(activityStatsUserVo.getActivityCancelledMoney()));
                    //总金额
                    todayStatsUserVo.setActivityTurnover(activityStatsUserVo.getActivityTurnover());

                }else if (BranchIdEnum.TURNOVER.getId().compareTo(statsUserDto.getBranchId()) == 0) {
                    //营业额
                    StatsUserVo onlineStatsUserVo = statsUserDao.findOrderStatistics(conditionStatsUserDto);
                    //现金收入
                    todayStatsUserVo.setCashMoney(onlineStatsUserVo.getCashMoney());
                    //在线收入
                    todayStatsUserVo.setTurnoverOnLine(onlineStatsUserVo.getTurnoverOnLine());
                    //活动收入
                    StatsUserVo activityStatsUserVo = statsUserDao.findActivityMoney(conditionStatsUserDto);
                    todayStatsUserVo.setActivityTurnover(activityStatsUserVo.getActivityTurnover());
                    todayStatsUserVo.setTurnover(onlineStatsUserVo.getTurnover().add(activityStatsUserVo.getActivityTurnover()));
                } else if (BranchIdEnum.DOUYIN.getId().compareTo(statsUserDto.getBranchId()) == 0) {
                    //抖音核销收入
                    StatsUserVo onlineStatsUserVo = statsUserDao.findOrderStatistics(conditionStatsUserDto);
                    todayStatsUserVo.setTurnoverDouYin(onlineStatsUserVo.getTurnoverDouYin());
                }else if (BranchIdEnum.MEITUAN.getId().compareTo(statsUserDto.getBranchId()) == 0) {
                    //美团核销收入
                    StatsUserVo onlineStatsUserVo = statsUserDao.findOrderStatistics(conditionStatsUserDto);
                    todayStatsUserVo.setTurnoverMeiTuan(onlineStatsUserVo.getTurnoverMeiTuan());
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                return todayStatsUserVo;
            }
        }, executor);
        //统计吧台和兑币机收现金
        if (BranchIdEnum.CASH_INCOME.getId().compareTo(statsUserDto.getBranchId()) == 0
            && !statsUserDto.getStartDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
            StatsStoreDto statsStoreDto = new StatsStoreDto();
            statsStoreDto.setType(StatisticsTypeEnum.DAY.getCode());
            statsStoreDto.setStartTime(statsUserDto.getStartDateStr());
            statsStoreDto.setEndTime(statsUserDto.getEndDateStr());
            statsStoreDto.setUserInfo(statsUserDto.getUserInfo());
            statsStoreDto.setMerchantStoreIdArray(statsUserDto.getMerchantStoreIdArray());
            //吧台
            StatsStoreVo otherStatsStoreDeviceNo = statsAppDeviceService.findStatsAppDeviceByMerchantStoreIdArray(statsStoreDto);
            //兑币机
            List<StatsStoreVo> statsStoreVoList = statsDeviceService.findStatsDeviceByMerchantStoreIdArray(statsStoreDto);

            StatsUserVo todayStatsUserVo = todayFuture.get();
            todayStatsUserVo.setManualTerminalCash(todayStatsUserVo.getManualTerminalCash().add(otherStatsStoreDeviceNo.getManualTerminalCash()));
            //包含当天 累加张数
            if (statsUserDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                statsStoreVoList.forEach(data->todayStatsUserVo.getStatsStoreDeviceNoList().forEach(item->{
                    if(data.getDeviceNo().equals(item.getDeviceNo())){
                        data.setOneYuanDenomination(data.getOneYuanDenomination()+item.getOneYuanDenomination());
                        data.setFiveYuanDenomination(data.getFiveYuanDenomination()+item.getFiveYuanDenomination());
                        data.setTenYuanDenomination(data.getTenYuanDenomination()+item.getTenYuanDenomination());
                        data.setTwentyYuanDenomination(data.getTwentyYuanDenomination()+item.getTwentyYuanDenomination());
                        data.setFiftyYuanDenomination(data.getFiftyYuanDenomination()+item.getFiftyYuanDenomination());
                        data.setOneHundredYuanDenomination(data.getOneHundredYuanDenomination()+item.getOneHundredYuanDenomination());
                        data.setSelfServiceTerminalCash(data.getSelfServiceTerminalCash().add(item.getSelfServiceTerminalCash()));
                    }
                }));
            }
            statsStoreVoList.forEach(data -> {
                // 计算每个面额的总额：1元 * 1张 = 1元
                data.setOneYuanDenominationTotal(BigDecimal.ONE.multiply(BigDecimal.valueOf(data.getOneYuanDenomination())));
                data.setFiveYuanDenominationTotal(BigDecimal.valueOf(5).multiply(BigDecimal.valueOf(data.getFiveYuanDenomination())));
                data.setTenYuanDenominationTotal(BigDecimal.TEN.multiply(BigDecimal.valueOf(data.getTenYuanDenomination())));
                data.setTwentyYuanDenominationTotal(BigDecimal.valueOf(20).multiply(BigDecimal.valueOf(data.getTwentyYuanDenomination())));
                data.setFiftyYuanDenominationTotal(BigDecimal.valueOf(50).multiply(BigDecimal.valueOf(data.getFiftyYuanDenomination())));
                data.setOneHundredYuanDenominationTotal(BigDecimal.valueOf(100).multiply(BigDecimal.valueOf(data.getOneHundredYuanDenomination())));

            });

            log.info("统计兑币机"+JSON.toJSONString(statsStoreVoList));
            todayStatsUserVo.setStatsStoreDeviceNoList(statsStoreVoList);
        }

        CompletableFuture<StatsStoreVo> otherDateFuture = CompletableFuture.supplyAsync(() -> {
            StatsStoreVo otherStatsStoreVo;
            try {
                StatsStoreDto statsStoreDto = new StatsStoreDto();
                statsStoreDto.setStatsType(StatsTypeEnum.statsUser.getCode());
                statsStoreDto.setType(StatisticsTypeEnum.DAY.getCode());
                statsStoreDto.setStartTime(statsUserDto.getStartDateStr());
                statsStoreDto.setEndTime(statsUserDto.getEndDateStr());
                statsStoreDto.setUserInfo(statsUserDto.getUserInfo());
                statsStoreDto.setMerchantStoreIdArray(statsUserDto.getMerchantStoreIdArray());
                if(!StringUtils.isEmpty(statsUserDto.getDeviceNo())){
                    //设备统计
                    statsStoreDto.setDeviceNo(statsUserDto.getDeviceNo());
                    otherStatsStoreVo = statsDeviceService.findStatsStoreByDeviceNo(statsStoreDto);
                    //合计投币
                    otherStatsStoreVo.setInsertCoinTotal(otherStatsStoreVo.getInsertCoinTotal());
                    otherStatsStoreVo.setInsertCoinOnLine(otherStatsStoreVo.getInsertCoinOnLine());
                    otherStatsStoreVo.setInsertCoinOffline(otherStatsStoreVo.getInsertCoinOffline());

                    //线上购币
                    otherStatsStoreVo.setOnLinePayOutCoinTotal(0);
                    //会员取币
                    otherStatsStoreVo.setFetchMemberOutCoinTotal(otherStatsStoreVo.getFetchMemberOutCoinTotal());
                    //抖音核销出币
                    otherStatsStoreVo.setDouYinOutCoinTotal(otherStatsStoreVo.getDouYinOutCoinTotal());
                    //美团核销出币
                    otherStatsStoreVo.setMeiTuanOutCoinTotal(otherStatsStoreVo.getMeiTuanOutCoinTotal());
                    //微信核销出币
                    otherStatsStoreVo.setWeiXinGroupBuyingOutCoinTotal(otherStatsStoreVo.getWeiXinGroupBuyingOutCoinTotal());
                    otherStatsStoreVo.setWeiXinVoucherOutCoinTotal(otherStatsStoreVo.getWeiXinVoucherOutCoinTotal());
                    otherStatsStoreVo.setWeiXinSeckillOutCoinTotal(otherStatsStoreVo.getWeiXinSeckillOutCoinTotal());

                    otherStatsStoreVo.setCashMoney(BigDecimal.ZERO);
                    otherStatsStoreVo.setTurnoverOnLine(BigDecimal.ZERO);
                    otherStatsStoreVo.setTurnoverOfflineCollectionCode(BigDecimal.ZERO);
                    otherStatsStoreVo.setScanCodePayTotalTurnover(BigDecimal.ZERO);
                    otherStatsStoreVo.setOutCoinTotal(0);
                    otherStatsStoreVo.setOnLineOutCoinTotal(0);
                    otherStatsStoreVo.setOffLinePayOutCoinTotal(0);
                    otherStatsStoreVo.setGameCoinRedPacketCoinTotal(0);
                    otherStatsStoreVo.setDistributeBenefitCoinTotal(0);
                    otherStatsStoreVo.setGroupBenefitCoinTotal(0);
                    otherStatsStoreVo.setGiftConsume(0);
                    otherStatsStoreVo.setArtificialOutCoinTotal(0);
                    otherStatsStoreVo.setTurnover(BigDecimal.ZERO);
                    otherStatsStoreVo.setTurnoverDouYin(BigDecimal.ZERO);
                    otherStatsStoreVo.setTurnoverMeiTuan(BigDecimal.ZERO);
                    otherStatsStoreVo.setActivityCancelledMoney(BigDecimal.ZERO);
                    otherStatsStoreVo.setActivityUnwrittenMoney(BigDecimal.ZERO);
                    otherStatsStoreVo.setActivityTurnover(BigDecimal.ZERO);
                }else{
                    otherStatsStoreVo = statsStoreService.findStatsStoreByMerchantStoreIdArray(statsStoreDto);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e.getMessage());
            }
            return otherStatsStoreVo;
        }, executor);

        CompletableFuture.allOf(todayFuture, otherDateFuture).get();

        StatsUserVo todayStatsUserVo = todayFuture.get();
        StatsStoreVo otherDateStatsUserVo = otherDateFuture.get();

        if (StringUtils.isEmpty(otherDateStatsUserVo)) {
            return ServerResponse.createBySuccess(todayStatsUserVo);
        }

        todayStatsUserVo.setCashMoney(todayStatsUserVo.getCashMoney().add(otherDateStatsUserVo.getCashMoney()));
        //线上扫码
        todayStatsUserVo.setTurnoverOnLine(todayStatsUserVo.getTurnoverOnLine().add(otherDateStatsUserVo.getTurnoverOnLine()));
        //线下扫码
        todayStatsUserVo.setTurnoverOfflineCollectionCode(todayStatsUserVo.getTurnoverOfflineCollectionCode().add(otherDateStatsUserVo.getTurnoverOfflineCollectionCode()));
        //扫码支付 =  线上扫码 + 线下扫码
        todayStatsUserVo.setScanCodePayTotalTurnover(todayStatsUserVo.getTurnoverOnLine().add(todayStatsUserVo.getTurnoverOfflineCollectionCode()));

        todayStatsUserVo.setOutCoinTotal(todayStatsUserVo.getOutCoinTotal() + otherDateStatsUserVo.getOutCoinTotal());
        todayStatsUserVo.setOnLineOutCoinTotal(
                todayStatsUserVo.getOnLineOutCoinTotal()
                        + otherDateStatsUserVo.getOnLinePayOutCoinTotal()
                        + otherDateStatsUserVo.getFetchMemberOutCoinTotal()
                        + otherDateStatsUserVo.getDouYinOutCoinTotal()
                        + otherDateStatsUserVo.getMeiTuanOutCoinTotal()
        );
        todayStatsUserVo.setOnLinePayOutCoinTotal(todayStatsUserVo.getOnLinePayOutCoinTotal() + otherDateStatsUserVo.getOnLinePayOutCoinTotal());
        todayStatsUserVo.setOffLinePayOutCoinTotal(todayStatsUserVo.getOffLinePayOutCoinTotal() + otherDateStatsUserVo.getOffLinePayOutCoinTotal());
        //会员取币
        todayStatsUserVo.setFetchMemberOutCoinTotal(todayStatsUserVo.getFetchMemberOutCoinTotal() + otherDateStatsUserVo.getFetchMemberOutCoinTotal());
        //抖音核销出币
        todayStatsUserVo.setDouYinOutCoinTotal(todayStatsUserVo.getDouYinOutCoinTotal() + otherDateStatsUserVo.getDouYinOutCoinTotal());
        //美团核销出币
        todayStatsUserVo.setMeiTuanOutCoinTotal(todayStatsUserVo.getMeiTuanOutCoinTotal() + otherDateStatsUserVo.getMeiTuanOutCoinTotal());
        //微信核销总出币
        todayStatsUserVo.setWeiXinVerifyTotalCoin(todayStatsUserVo.getWeiXinVerifyTotalCoin()+
                otherDateStatsUserVo.getWeiXinGroupBuyingOutCoinTotal()+
                otherDateStatsUserVo.getWeiXinVoucherOutCoinTotal()+
                otherDateStatsUserVo.getWeiXinSeckillOutCoinTotal());
        //人工出币
        todayStatsUserVo.setArtificialOutCoinTotal(todayStatsUserVo.getArtificialOutCoinTotal()+otherDateStatsUserVo.getArtificialOutCoinTotal());
        todayStatsUserVo.setInsertCoinTotal(todayStatsUserVo.getInsertCoinTotal() + otherDateStatsUserVo.getInsertCoinTotal());
        todayStatsUserVo.setInsertCoinOnLine(todayStatsUserVo.getInsertCoinOnLine() + otherDateStatsUserVo.getInsertCoinOnLine());
        todayStatsUserVo.setInsertCoinOffline(todayStatsUserVo.getInsertCoinOffline() + otherDateStatsUserVo.getInsertCoinOffline());
        todayStatsUserVo.setGameCoinRedPacketCoinTotal(todayStatsUserVo.getGameCoinRedPacketCoinTotal() + otherDateStatsUserVo.getGameCoinRedPacketCoinTotal());
        todayStatsUserVo.setDistributeBenefitCoinTotal(todayStatsUserVo.getDistributeBenefitCoinTotal() + otherDateStatsUserVo.getDistributeBenefitCoinTotal());
        todayStatsUserVo.setGroupBenefitCoinTotal(todayStatsUserVo.getGroupBenefitCoinTotal() + otherDateStatsUserVo.getGroupBenefitCoinTotal());
        //消耗礼品
        todayStatsUserVo.setGiftConsume(todayStatsUserVo.getGiftConsume() + otherDateStatsUserVo.getGiftConsume());
        //营业额
        todayStatsUserVo.setTurnover(
                todayStatsUserVo.getTurnover()
                        .add(otherDateStatsUserVo.getCashMoney())
                        .add(otherDateStatsUserVo.getTurnoverOnLine())
                        .add(otherDateStatsUserVo.getTurnoverDouYin())
                        .add(otherDateStatsUserVo.getTurnoverMeiTuan()));
        //抖音核销收入
        todayStatsUserVo.setTurnoverDouYin(todayStatsUserVo.getTurnoverDouYin().add(otherDateStatsUserVo.getTurnoverDouYin()));
        //美团核销收入
        todayStatsUserVo.setTurnoverMeiTuan(todayStatsUserVo.getTurnoverMeiTuan().add(otherDateStatsUserVo.getTurnoverMeiTuan()));
        //活动已核销金额
        todayStatsUserVo.setActivityCancelledMoney(todayStatsUserVo.getActivityCancelledMoney().add(otherDateStatsUserVo.getActivityCancelledMoney()));
        //活动未核销金额
        todayStatsUserVo.setActivityUnwrittenMoney(todayStatsUserVo.getActivityUnwrittenMoney().add(otherDateStatsUserVo.getActivityUnwrittenMoney()));
        otherDateStatsUserVo.setActivityTurnover(
                otherDateStatsUserVo.getSeckillMoney().
                add(otherDateStatsUserVo.getGroupBookingMoney()
                .add(otherDateStatsUserVo.getConsumptionOfRedEnvelopesMoney()
                .add( otherDateStatsUserVo.getMemberOfTheStoredValueMoney())))
        );
        //活动营业额
        todayStatsUserVo.setActivityTurnover(
                todayStatsUserVo.getActivityTurnover()
                .add(otherDateStatsUserVo.getActivityTurnover()));

        return ServerResponse.createBySuccess(todayStatsUserVo);
    }

    /**
     * 运营统计分支，点击 投币，出币，营业额等进入详情统计-中部
     *
     * @param statsUserDto
     * @return
     */
    @Override
    public ServerResponse findStatsBranchData(StatsUserDto statsUserDto) {
        if (StringUtils.isEmpty(statsUserDto.getBranchId())) {
            return ServerResponse.createByErrorMessage("分支统计ID不能为空");
        }

        if (StringUtils.isEmpty(statsUserDto.getStartDateStr())) {
            return ServerResponse.createByErrorMessage("开始时间不能为空");
        }

        if (StringUtils.isEmpty(statsUserDto.getEndDateStr())) {
            return ServerResponse.createByErrorMessage("结束时间不能为空");
        }

        PageHelper.startPage(statsUserDto.getPageNum(), statsUserDto.getPageSize());
        Date date = new Date();
        String pattern = "HH";
        Locale locale = Locale.getDefault();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, locale);
        String time = simpleDateFormat.format(date);
        Integer hour = Integer.parseInt(time);
         String startTime;
         String endTime;
        if(hour >= 0 && hour <= 5 && statsUserDto.getDateType().compareTo(1)==0){
            startTime = DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.START_DATETIME_FORMATTER);
            endTime = DateTimeUtils.parseLocalDate(DateTimeUtils.getYesterday()).format(DateTimeUtils.END_DATETIME_FORMATTER);
        }else{
            startTime = DateTimeUtils.parseLocalDate(statsUserDto.getStartDateStr()).format(DateTimeUtils.START_DATETIME_FORMATTER);
            endTime = DateTimeUtils.parseLocalDate(statsUserDto.getEndDateStr()).format(DateTimeUtils.END_DATETIME_FORMATTER);

        }
        // 封装现金、线上收益条件参数
        OrderDto orderDto = new OrderDto();
        if (
                BranchIdEnum.CASH_INCOME.getId().compareTo(statsUserDto.getBranchId()) == 0
                        || BranchIdEnum.ONLINE_REVENUE.getId().compareTo(statsUserDto.getBranchId()) == 0
                        || BranchIdEnum.TURNOVER.getId().compareTo(statsUserDto.getBranchId()) == 0
                        || BranchIdEnum.MEITUAN.getId().compareTo(statsUserDto.getBranchId()) == 0
                        || BranchIdEnum.DOUYIN.getId().compareTo(statsUserDto.getBranchId()) == 0
        ) {
            orderDto.setUserInfo(statsUserDto.getUserInfo());
            orderDto.setStartTime(startTime);
            orderDto.setEndTime(endTime);
            orderDto.setMerchantStoreIdArray(statsUserDto.getMerchantStoreIdArray());
        }
        PageInfo pagResult;
        if (BranchIdEnum.CASH_INCOME.getId().compareTo(statsUserDto.getBranchId()) == 0) {
            // 现金
            orderDto.setMchType(MchTypeEnum.CASH_RECEIPTS.getCode());
            List<OrderVo> orderVoList = orderService.findOrderListByBranch(orderDto);
            pagResult = new PageInfo(orderVoList);
        } else if (BranchIdEnum.ONLINE_REVENUE.getId().compareTo(statsUserDto.getBranchId()) == 0) {
            // 扫码支付 = 线上支付 + 线下扫码
//            orderDto.setMchType(MchTypeEnum.OWN.getCode());
            List<OrderVo> orderVoList = orderService.findOrderListByBranchScanCode(orderDto);
            pagResult = new PageInfo(orderVoList);
        } else if (BranchIdEnum.TURNOVER.getId().compareTo(statsUserDto.getBranchId()) == 0) {
            //营业额
            // 现金 和 在线支付
            orderDto.setMchTypeArray(new Integer[]{
                    MchTypeEnum.CASH_RECEIPTS.getCode(),
                    MchTypeEnum.OWN.getCode(),
            });
            //合并语句
            List<OrderVo> orderVoList = orderService.findOrderListCashAndOwn(orderDto);
            pagResult = new PageInfo(orderVoList);
        }else if (BranchIdEnum.DOUYIN.getId().compareTo(statsUserDto.getBranchId()) == 0){
            //抖音核销套餐详情
            orderDto.setMchType(MchTypeEnum.DOUYIN_GROUP_PURCHASE.getCode());
            List<OrderVo> orderVoList = orderService.findOrderListByBranch(orderDto);
            pagResult = new PageInfo(orderVoList);
        }else if (BranchIdEnum.MEITUAN.getId().compareTo(statsUserDto.getBranchId()) == 0){
            //美团核销套餐详情
            orderDto.setMchType(MchTypeEnum.MEITUAN_GROUP_PURCHASE.getCode());
            List<OrderVo> orderVoList = orderService.findOrderListByBranch(orderDto);
            pagResult = new PageInfo(orderVoList);
        }else {
            throw new RuntimeException("分支ID暂无统计");
        }

        return ServerResponse.createBySuccess(pagResult);
    }

    @Override
    public StatsUserVo findStatsUserTwo(StatsUserDto statsUserDto) {
        statsUserDto.setStatsType(StatsTypeEnum.statsUser.getCode());

        StatsUserVo todayStatsUserVo;
        StatsUserVo thisMonthStatsUserVo;
        StatsUserVo statsUserVo = null;
        //当天
        if (statsUserDto.getDayType() == 0) {
            statsUserVo = this.findTodayStatsUserFromOrder(statsUserDto);
        } else if (statsUserDto.getDayType() == -1) {
            //根据日期范围查询
            statsUserDto.setType(1);
            statsUserVo = this.findFromStatsUser(statsUserDto);

            if (statsUserDto.getEndDateStr().equals(DateTimeUtils.getCurrentDateStr())) {
                todayStatsUserVo = this.findTodayStatsUserFromOrder(statsUserDto);
                this.twoStatsUserVoAdd(statsUserVo, todayStatsUserVo);
            }
        } else {
            switch (statsUserDto.getDayType()) {
                case 1:
                    //凌晨0点到六点调用实时统计的方法
                    Date date = new Date();
                    String pattern = "HH";
                    Locale locale = Locale.getDefault();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, locale);
                    String time = simpleDateFormat.format(date);
                    Integer hour = Integer.parseInt(time);
                    if(hour >= 0 && hour <= 5){
                        statsUserDto.setHour(hour);
                        statsUserVo = this.findTodayStatsUserFromOrder(statsUserDto);
                    }else{
                        //昨天
                        statsUserDto.setStartDateStr(DateTimeUtils.getYesterday());
                        statsUserDto.setEndDateStr(DateTimeUtils.getYesterday());
                        statsUserDto.setType(1);
                        statsUserVo = this.findFromStatsUser(statsUserDto);
                    }
                    break;
                case 2:
                    //本周
                    statsUserDto.setStartDateStr(DateTimeUtils.getWeekFirstDay());
                    statsUserDto.setEndDateStr(DateTimeUtils.getCurrTime());
                    statsUserDto.setType(1);
                    statsUserVo = this.findFromStatsUser(statsUserDto);
                    //当天
                    todayStatsUserVo = this.findTodayStatsUserFromOrder(statsUserDto);
                    this.twoStatsUserVoAdd(statsUserVo, todayStatsUserVo);
                    break;
                case 3:
                    //本月
                    statsUserVo = this.getThisMonth(statsUserDto);
                    break;
                case 4:
                    //今年
                    statsUserDto.setStartDateStr(DateTimeUtils.getYearFirstDayTimeYM());
                    statsUserDto.setEndDateStr(DateTimeUtils.getMonthYM());
                    statsUserDto.setType(2);
                    statsUserVo = this.findFromStatsUser(statsUserDto);
                    //本月
                    thisMonthStatsUserVo = this.getThisMonth(statsUserDto);
                    this.twoStatsUserVoAdd(statsUserVo, thisMonthStatsUserVo);
                    break;
                case 5:
                    //上月
                    statsUserDto.setStartDateStr(DateTimeUtils.getPreviousMonthYM());
                    statsUserDto.setEndDateStr(DateTimeUtils.getPreviousMonthYM());
                    statsUserDto.setType(2);
                    statsUserVo = this.findFromStatsUser(statsUserDto);
                    break;
            }
        }
        //全部场地
        List<MerchantStoreVo> merchantStoreVoList = merchantStoreService.findMerchantStoreIdByUserId(statsUserDto.getUserInfo());
        statsUserVo.setMerchantStoreVoList(merchantStoreVoList);
        statsUserVo.setTotalMerchantStore(merchantStoreVoList.size());

        //全部设备
        DeviceDto deviceDto = new DeviceDto();
        deviceDto.setUserInfo(statsUserDto.getUserInfo());
        Integer totalDevice = deviceService.findDeviceCountByUserId(deviceDto);

        statsUserVo.setTotalDevice(totalDevice);

        switch (statsUserDto.getDayType()) {
            case 0:
                statsUserVo.setStartDateStr(DateTimeUtils.getCurrentDateStr());
                statsUserVo.setEndDateStr(DateTimeUtils.getCurrentDateStr());
                break;
            case 2:
                statsUserVo.setStartDateStr(DateTimeUtils.getWeekFirstDay());
                statsUserVo.setEndDateStr(DateTimeUtils.getCurrTime());
                break;
            case 3:
                statsUserVo.setStartDateStr(DateTimeUtils.getMonthFirstDay());
                statsUserVo.setEndDateStr(DateTimeUtils.getCurrTime());
                break;
            case 4:
                statsUserVo.setStartDateStr(DateTimeUtils.getYearFirstDayTimeYMD());
                statsUserVo.setEndDateStr(DateTimeUtils.getCurrTime());
                break;
            case 5:
                statsUserVo.setStartDateStr(DateTimeUtils.getPreviousMonthFirstDay());
                statsUserVo.setEndDateStr(DateTimeUtils.getPreviousMonthLastDay());
                break;
            default:
                statsUserVo.setStartDateStr(statsUserDto.getStartDateStr());
                statsUserVo.setEndDateStr(statsUserDto.getEndDateStr());
                break;
        }
        return statsUserVo;
    }

    public static void main(String[] args) {
        StatsUserVo statsUserVo = new StatsUserVo();
        statsUserVo.setId(111L);


        StatsUserVo statsUserVo2 = new StatsUserVo();
        statsUserVo2.setOneYuanDenomination(11);

        BeanUtils.copyProperties(statsUserVo2, statsUserVo, "id");

        System.out.println(statsUserVo.getId());
        System.out.println(statsUserVo.getOneYuanDenomination());
    }
}
